using System;
using DataLayer.Repositories;
using DbEntities.Entities;
using EsbMonitor.Ninject;
using EsbMonitorMessages;
using log4net;
using NServiceBus;

namespace EsbMonitor.Handlers
{
    public class NewSubscriptionEventHandler : IHandleMessages<INewSubscriptionEvent>
    {
        private static readonly ILog Logger = LogManager.GetLogger(typeof (NewSubscriptionEventHandler));
        public IBus Bus { get; set; }

        #region IHandleMessages<INewSubscriptionEvent> Members

        public void Handle(INewSubscriptionEvent message)
        {
            var messageAssembliesRepository = KernelContainer.Get<IMessageAssembliesRepository>();
            var publishersRepository = KernelContainer.Get<IPublishersRepository>();
            var subscribersRepository = KernelContainer.Get<ISubscribersRepository>();
            var subscriptionsRepository = KernelContainer.Get<ISubscriptionsRepository>();

            Publisher publisher = publishersRepository.FindByInputQueueName(message.PublisherQueueName);

            if (publisher == null)
            {
                throw new ApplicationException("Unknown Publisher: " + message.PublisherQueueName);
            }

            MessageAssembly messageAssembly =
                messageAssembliesRepository.FindByMessageAssemblyVersionId(message.MessageAssemblyVersionId);

            if (messageAssembly == null)
            {
                throw new ApplicationException("Unknown MessageAssembly: " + message.MessageAssemblyVersionId);
            }


            Subscriber subscriber = subscribersRepository.FindByInputQueueName(message.SubscriberQueueName);

            if (subscriber == null)
            {
                subscriber = new Subscriber
                                 {
                                     FirstSeen = DateTime.Now,
                                     InputQueueName = message.SubscriberQueueName,
                                     LastSeen = DateTime.Now
                                 };

                subscribersRepository.Add(subscriber);
            }


            string messageType = message.TypeName;
            Subscription subscription = subscriptionsRepository.Find(subscriber, publisher, messageType, messageAssembly);

            if (subscription == null)
            {
                Logger.Info("Persisting Subscription");

                subscription = new Subscription
                                   {
                                       MessageAssembly = messageAssembly,
                                       MessageType = messageType,
                                       PublishedBy = publisher,
                                       SubscribedBy = subscriber
                                   };

                subscriptionsRepository.Add(subscription);
            }
            else
            {
                Logger.Info("Subscription already persisted");
            }
        }

        #endregion
    }
}